package castle.defense.project;

import android.graphics.Color;

/**
 * Class defining a weapon that can be owned by the player or an enemy.
 * Weapons may create projectiles and have a certain range, radius of 
 * effect, damage amount, and minimum time between successive attacks.
 * Weapons may be bought by the player from the item store.
 * 
 * @author KevinJoslyn
 *
 */
public class Weapon extends Item
{
	//determined by us, arbitrary units
	int attackSound, attackDamage;
	
	//Time units for attacking
	double timeElapsed, attackSpeed;
	
	//based on screen size
	double range, projectileSpeed;
	float size;
	
	int color;
	
	//whether or not the projectile is aimed at the player
	boolean offensive, visibleProj;
	
	/** Basic weapon constructor.
	 * 
	 * @param cost		The cost of the weapon, in credits.
	 * @param avatar	The hash key representing this weapon's avatar (image)
	 * @param sound		The hash key representing this weapon's attack sound
	 * @param speed		The minimum time between successive attacks by this
	 * 					weapon.
	 * @param damage	The amount of damage caused by this weapon's attack.
	 * @param range		The range of this weapon (abstract units.)
	 * @param size		The radius of effect of this weapon's attack (abstract units.)
	 */
	public Weapon(int cost, int avatar) {
		
		super(cost, avatar);
		//Sets defaults
		this.attackSound = -1;
		this.timeElapsed = 0;
		this.attackSpeed = 0;
		this.attackDamage = 0;
		this.projectileSpeed = 0;
		this.range = 1;
		this.size = 1;
		this.offensive = true;
		this.color = Color.BLACK;
		this.visibleProj = true;
	}
	
	public Weapon(double attackSpeed, int attackDamage, double range, double size, double projectileSpeedPercent, int color, boolean offensive) {
		this(-1,-1);
		this.setAttackDamage(attackDamage);
		this.setAttackSpeed(attackSpeed);
		this.setRange(range);
		this.setSize(size);
		this.setProjectileSpeedPercent(projectileSpeedPercent);
		this.setColor(color);
		this.offensive = offensive;
	}
	
	public Weapon(double attackSpeed, int attackDamage, double range, double size, double projectileSpeedPercent, int color, boolean offensive, int attackSound) {
		this(attackSpeed,attackDamage,range,size,projectileSpeedPercent,color,offensive);
		this.attackSound = attackSound;
	}
	
	public Weapon(double attackSpeed, int attackDamage, double range, double size, double projectileSpeedPercent, int color, boolean offensive, int attackSound, boolean visible) {
		this(attackSpeed,attackDamage,range,size,projectileSpeedPercent,color,offensive,attackSound);
		this.visibleProj = visible;
	}
	
	public boolean canAttack() {
		return timeElapsed >= attackSpeed;
	}
	
	public boolean inRange(double y) {
		return y-Castle.top <= range;
	}
	
	public Projectile attack(double xat, double yat, double x, double y) {
		if(!canAttack())
			return null;
		this.makeSound();
		timeElapsed = 0;
		Projectile p = new Projectile(xat,yat,projectileSpeed(projectileSpeed, Math.atan2(y-yat,x-xat)),Math.atan2(y-yat, x-xat),size,attackDamage,offensive,visibleProj);
		p.setColor(color);
		return p;
	}
	
	public static Weapon createBallista() {
		Weapon ballista = new Weapon(-1,-1);
		ballista.setAttackSpeed(1.25);
		ballista.setAttackDamage(5);
		ballista.setRange(50);
		ballista.setSize(10);
		ballista.setProjectileSpeedPercent(15);
		return ballista;
	}
	
	public static Weapon createEnemyGun() {
		//constants for a gun.
		return new Weapon(1,5,15,1,25,Color.YELLOW,true,SoundManager.gun);
	}
			 
	public static ImmobileWeapon createGun() {
		//constants for a gun.
		return new ImmobileWeapon(new PhysicsPoint(PE.screenPercentX(50),Castle.top),0.25,15,15,1,25,Color.WHITE,false,SoundManager.gun,true);
	}
	
	public static Weapon createMelee(double size, int ad, double as) {
		return new Weapon(as,ad,size,1,25,Color.TRANSPARENT,true,SoundManager.slam,false);
	}
	
	public void setAttackSpeed(double as) {
		attackSpeed = as;
	}
	
	public void setAttackDamage(int ad) {
		attackDamage = ad;
	}
	
	public void setRange(double percent) {
		range = PE.screenPercentY(percent);
	}
	
	public void setProjectileSpeedPercent(double percent) {
		projectileSpeed = percent;
	}
	
	public void setSize(double percent) {
		size = (float)PE.screenPercentX(percent);
	}
	
	public void setColor(int c) {
		color = c;
	}
	
	public double projectileSpeed(double speed, double angle) {
		return Math.abs(Math.cos(angle) * PE.screenPercentX(speed)) + Math.abs(Math.sin(angle) * PE.screenPercentY(speed));
	}
	
	public void update(long milli) {
		timeElapsed+=milli/1000.0;
	}
	
	/**
	 * Upon firing, the weapon will tell the sound engine to 
	 * make the appropriate sound.
	 * 
	 * @see 	SoundManager
	 */
	public void makeSound() {
		if(attackSound >= 0)
			SoundManager.playSound(attackSound);
	}
}
